/**
 *
 */
package com.newer.biz.sys.role.impl;

import com.baomidou.mybatisplus.plugins.Page;
import com.newer.biz.sys.role.RoleInfoBiz;
import com.newer.commons.constants.CommonConstants;
import com.newer.commons.constants.StateConstants;
import com.newer.commons.result.BizResult;
import com.newer.dao.bean.sys.*;
import com.newer.dao.mapper.sys.*;
import com.newer.utils.ShiroAuthUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.newer.utils.GenIdUtils.genId;
import static com.newer.utils.ShiroAuthUtils.getAuthUser;

/**
 * 角色信息操作业务实现类
 *
 * @author xuntj
 * @create 2018-03-20 9:37
 **/
@Component
public class RoleInfoBizImpl implements RoleInfoBiz {

    /**
     * 日志信息打印
     */
    Logger logger = LogManager.getLogger(this.getClass());

    /**
     * 角色信息Mapper代理
     */
    @Autowired
    RoleMapper roleMapper;

    /**
     * 角色-菜单信息Mapper代理
     */
    @Autowired
    RoleMenuMapper roleMenuMapper;

    /**
     * 菜单信息Mapper代理
     */
    @Autowired
    MenuMapper menuMapper;

    /**
     * 角色权限信息查询
     */
    @Autowired
    RolePermissionMapper rolePermissionMapper;

    /**
     * 角色权限信息查询
     */
    @Autowired
    PermissionMapper permissionMapper;

    /**
     * 查询角色信息列表
     *
     * @param query
     * @return
     */
    @Override
    public BizResult<Role> queryRoleInfoByPage(Role query) {
        BizResult<Role> bizResult = new BizResult<>();
        try {
            // 分页器进行分页
            Page<Role> pageInfo = new Page<>(query.getPageNo(), query.getPageSize());
            // 返回分页结果类
            List<Role> roles = roleMapper.selectByParams(pageInfo, query);
            pageInfo.setRecords(roles);
            bizResult.setPageInfo(pageInfo);
            bizResult.setSuccess(true);
        } catch (Exception e) {
            logger.error("分页查询角色信息列表,失败原因:" + e.getCause(), e);
            bizResult.setMsg("分页查询角色信息列表,请联系开发人员.");
        }
        return bizResult;
    }

    /**
     * 查询角色-菜单信息数据
     *
     * @param roleId
     * @return
     */
    @Override
    public BizResult<Menu> queryRoleMenuInfos(String roleId) {
        BizResult<Menu> bizResult = new BizResult<>();
        try {
            // 返回分页结果类
            List<String> menuIds = roleMenuMapper.selectMenuIdsByRoleId(roleId);
            // 判断菜单Id集合是否为空
            if (CollectionUtils.isNotEmpty(menuIds)) {
                // 根据菜单ID查询菜单信息
                List<Menu> menus = menuMapper.selectMenusByIds(menuIds, CommonConstants.IS_MENU);
                bizResult.setResults(menus);
            }
            bizResult.setSuccess(true);
        } catch (Exception e) {
            logger.error("分页查询角色-菜单信息数据失败,失败原因:" + e.getCause(), e);
            bizResult.setMsg("查询角色-菜单信息数据失败,请联系开发人员.");
        }
        return bizResult;
    }


    /**
     * 根据角色Code查询权限信息
     *
     * @param roleId
     * @return
     */
    @Override
    public BizResult<RolePermission> queryRolePermissionByRoleId(String roleId) {
        BizResult<RolePermission> bizResult = new BizResult<>();
        try {
            // 返回分页结果类
            Map<String, Object> maps = new HashMap<>();
            maps.put("role_id", roleId);
            List<RolePermission> rolePermissions = rolePermissionMapper.selectByMap(maps);
            bizResult.setResults(rolePermissions);
            bizResult.setSuccess(true);
        } catch (Exception e) {
            logger.error("根据角色Code查询权限信息数据失败,失败原因:" + e.getCause(), e);
            bizResult.setMsg("根据角色Code查询权限信息失败,请联系开发人员.");
        }
        return bizResult;
    }

    /**
     * 角色信息相关操作
     *
     * @param role
     * @param menuIds
     * @param permissionIds
     * @return
     */
    @Override
    public BizResult<Role> operateRoleInfo(Role role, List<String> menuIds, List<String> permissionIds) {
        BizResult<Role> bizResult = new BizResult<>();
        try {
            // 判断是否新增菜单
            if (StringUtils.isNotBlank(role.getId())) {
                // 查询所有的菜单信息
                roleMapper.updateById(role);
                // 判断是否存在权限信息
                Map<String, Object> maps = new HashMap<>();
                maps.put("role_id", role.getId());
                // 删除所有关联数据
                rolePermissionMapper.deleteByMap(maps);
                // 删除所有关联数据
                roleMenuMapper.deleteByMap(maps);
            } else {
                // 修改菜单操作
                User user = getAuthUser(SecurityUtils.getSubject());
                // 判断类型是否为菜单类型
                role.setId(genId());
                role.setCreateTime(new Date());
                role.setStatus(StateConstants.VALIDE);
                role.setCreateId(user.getId());
                role.setCreater(user.getRealName());
                roleMapper.insertSelective(role);
            }
            // 判断是否为空
            if (CollectionUtils.isNotEmpty(menuIds)) {
                // 循环设置的权限ID
                for (String menuId : menuIds) {
                    RoleMenu roleMenu = new RoleMenu();
                    // 查询权限信息
                    roleMenu.setId(genId());
                    roleMenu.setRoleId(role.getId());
                    roleMenu.setRoleCode(role.getRoleCode());
                    roleMenu.setMenuId(menuId);
                    //插入数据
                    roleMenuMapper.insert(roleMenu);
                }
            }
            // 判断是否为空
            if (CollectionUtils.isNotEmpty(permissionIds)) {
                // 循环设置的权限ID
                for (String permissionId : permissionIds) {
                    RolePermission rolePermission = new RolePermission();
                    // 查询权限信息
                    Permission permission = permissionMapper.selectByPrimaryKey(permissionId);
                    rolePermission.setPermissionCode(permission.getPermissionCode());
                    rolePermission.setId(genId());
                    rolePermission.setPermissionId(permissionId);
                    rolePermission.setRoleId(role.getId());
                    rolePermission.setRoleCode(role.getRoleCode());
                    rolePermission.setPermissionName(permission.getPermissionName());
                    //插入数据
                    rolePermissionMapper.insertSelective(rolePermission);
                }
            }
            // 清空权限
            ShiroAuthUtils.clearAllAuth();

            bizResult.setResult(role);
            bizResult.setSuccess(true);
        } catch (Exception e) {
            logger.error("角色信息相关操作,失败原因:" + e.getCause(), e);
            bizResult.setMsg("角色信息相关操作,请联系开发人员.");
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return bizResult;
    }

    /**
     * 查询角色信息
     *
     * @param roleId
     * @return
     */
    @Override
    public BizResult<Role> queryRoleInfoById(String roleId) {
        BizResult<Role> bizResult = new BizResult<>();
        try {
            // 返回分页结果类
            Role role = roleMapper.selectById(roleId);
            bizResult.setResult(role);
            bizResult.setSuccess(true);
        } catch (Exception e) {
            logger.error("根据Id查询角色信息列表,失败原因:" + e.getCause(), e);
            bizResult.setMsg("根据Id查询角色信息列表,请联系开发人员.");
        }
        return bizResult;
    }

    /**
     * 根据角色Id查询菜单信息,并标识哪些菜单已拥有
     *
     * @param roleId
     * @return
     */
    @Override
    public BizResult<Menu> queryRoleMenuCheckedInfos(String roleId) {
        BizResult<Menu> bizResult = new BizResult<>();
        try {
            // 返回分页结果类
            List<Menu> menus = menuMapper.selectRoleMenuChecked(roleId);
            bizResult.setResults(menus);
            bizResult.setSuccess(true);
        } catch (Exception e) {
            logger.error("根据角色Id查询菜单信息,并标识哪些菜单已拥有失败,失败原因:" + e.getCause(), e);
            bizResult.setMsg("根据角色Id查询菜单信息,并标识哪些菜单已拥有失败,请联系开发人员.");
        }
        return bizResult;
    }

    /**
     * 异步校验角色Code
     *
     * @param roleCode
     * @return
     */
    @Override
    public BizResult<String> checkRoleCodeExits(String roleCode) {
        BizResult<String> bizResult = new BizResult<>();
        try {
            Role query = new Role();
            query.setRoleCode(roleCode);
            Role role = roleMapper.selectOne(query);
            bizResult.setSuccess(true);
            if (role != null) {
                bizResult.setResult(role.getId());
            }
        } catch (Exception e) {
            logger.error("异步校验权限Code失败,失败原因:" + e.getCause(), e);
            bizResult.setMsg("异步校验权限Code失败,请联系开发人员.");
        }
        return bizResult;
    }

    /**
     * 根据角色Id删除角色
     *
     * @param role
     * @return
     */
    @Override
    @Transactional
    public BizResult<?> delRoleById(Role role) {
        BizResult<String> bizResult = new BizResult<>();
        try {
            // 设置对象
            // 删除角色信息
            roleMapper.updateById(role);
            // 删除关联数据
            Map<String, Object> maps = new HashMap<>();
            maps.put("role_id", role.getId());
            //删除关联数据
            roleMenuMapper.deleteByMap(maps);
            rolePermissionMapper.deleteByMap(maps);
            bizResult.setSuccess(true);
        } catch (Exception e) {
            logger.error("根据角色Id删除角色失败,失败原因:" + e.getCause(), e);
            bizResult.setMsg("根据角色Id删除角色失败,请联系开发人员.");
        }
        return bizResult;
    }
}
